
function generateRandomId(): string {
    return Math.random().toString(36).substring(2, 9); // 生成一个9位的随机字符串
}

function generateTimestampId(): string {
    return Date.now().toString(36); // 转换为36进制以减少长度
}

export class WebSocketWrapper {
    id: string
    url:string
    ws?:WebSocket
    pingTimer: number
    activeClose:boolean
    cb:(event:any)=>void
    constructor(url: string, cb:(event:any)=>void|undefined) {
        this.id = this.genId()
        this.url = url
        if (cb != undefined) {
            this.cb = cb
        }
        this.activeClose = false
        this.ws = this.create()

    }

    startPing(): void {
        this.pingTimer = setInterval(() => {
            this.ping()
        }, 3*1000)
    }

    setListener(cb:(event:any)=>void):void {
        this.cb = cb
    }

    ping() {
        if (this.ws?.readyState === WebSocket.OPEN) {
            this.ws.send("ping")
        }
    }

    genId(): string {
        return generateRandomId() + generateTimestampId()
    }

    create(): WebSocket {
        if (this.ws != null) {
            this.ws = null
        }
        this.ws = new WebSocket(this.url);
        this.config()
        return this.ws
    }

    recreate() {
        console.log("reconnect")
        this.clearConfig()
        setTimeout(() => {
            this.ws = this.create()
        }, 2000)
    }

    clearConfig() {
        let ws = this.ws!
        this.ws = undefined
        ws.onclose = ()=>{}
        ws.onerror = ()=>{}
        ws.onopen = ()=>{}
        ws.onmessage = ()=>{}
        try {
            ws.close()
        } catch (e) {
            console.log(e)
        }
    }

    config() {
        let ws = this.ws as WebSocket
        ws.onopen = ()=> {
            console.log("ws opened:", this.id, this.url)
        }
        ws.onerror = (err: any) => {
            console.log("ws error:", this.url, err)
            this.recreate()
        }
        ws.onclose = () => {
            console.log("ws closed:",this.id, this.url)
            if (this.activeClose) {
                return
            }
            this.recreate()
        }
        ws.onmessage = (msg) => {
            if (this.cb != null) {
                let obj = JSON.parse(msg.data)
                this.cb(obj)
            }
        }
    }
    close() {
        this.activeClose = true
        clearInterval(this.pingTimer)
        let ws = this.ws!
        ws.close()
    }
}